
#include <Store.h>

Store::Store() : head(0), num(0)
{
}

Store::Store(TokensIter ti) : head(0), num(0)
{
	read(ti);
}

Store::Store(char* input) : head(0), num(0)
{
	read(input);
}

Store::Store(char* input, char* sep) : head(0), num(0)
{
	read(input, sep);
}

Node* Store::allocNode(Element elem)
{
	Node* temp;
	temp = new Node;
	temp->element = elem;
	temp->next = 0;
	return temp;
}

void Store::read(TokensIter ti)
{
	for ( ; ti.ok(); ti++ )
		add(ti.current()->element);
}

void Store::read(char* input, char* sep)
{
	Tokens tokens(input, sep);
	TokensIter ti(tokens);
	read(ti);
}

void Store::read(char* input)
{
	read(input, " ,=:");
}

void Store::add(Element elem)
{
	Node *newNode, *trav;

	if ( ifExists(elem) ) return;

	newNode = allocNode(elem);

	if ( !head )
		head = newNode;
	else {
		for ( trav = head; trav->next; trav = trav->next ) ;
		trav->next = newNode;
	}
	num++;
}

int Store::ifExists(Element elem)
{
	Node* trav;
	if ( head ) {
		for ( trav = head; trav; trav = trav->next )
			if ( trav->element == elem )
				return 1;
	}
	return 0;
}

int Store::numElements() const
{
	return num;
}

Element* Store::getElements(int& numElements)
{
	Element* elements;
	Node* trav;
	int i;

	elements = new Element[num];
	for ( i = 0, trav = head; trav; i++, trav = trav->next ) {
		elements[i] = trav->element;
	}
	numElements = num;
	return elements;
}

void Store::deleteAll()
{
	Node* trav;
	for ( trav = head; trav; trav = head ) {
		head = head->next;
		delete trav;
	}
}

Store::~Store()
{
	deleteAll();
}

ostream& operator<<(ostream& os, const Store& store)
{
	//os << store.numElements() << " ";
	for ( StoreIter si(store); si.ok(); si++ )
		os << si.current()->element << " ";
	
	return os;
}


//
// Store Iterator
//

StoreIter::StoreIter(const Store& aStore)
{
	store = &aStore;
	curr = store->head;
}

void StoreIter::reset()
{
	curr = store->head;
}

int StoreIter::ok()
{
//	if ( curr->next ) return 1;
	if ( curr ) return 1;
	return 0;
}

void StoreIter::operator++()
{
	if ( curr ) curr = curr->next;
}

Node* StoreIter::current()
{
	return curr;
}

